package com.e2u.test;

import com.e2u.classloader.FileSystemClassLoader;
import com.e2u.util.SystemUtil;

public class Main
{

	public static void classInDiffClassLoader()
	{
		ClassLoader cl = com.e2u.test.obj.ObjectInf.class.getClassLoader();
		System.out.println("ObjectInf's ClassLoader = " + cl);
		
		com.e2u.test.obj.ObjectInf defBaseObj = testLoadClass("com.e2u.test.obj.Foo", true);
		com.e2u.test.obj.ObjectInf baseObj = testLoadClass("com.e2u.test.obj.Foo", false);
		com.e2u.test.obj.ObjectInf subObj = testLoadClass("com.e2u.test.obj.Too", false);
		
		baseObj = subObj;		
		baseObj.sayHello();
	}
	
	private static com.e2u.test.obj.ObjectInf testLoadClass(String name, boolean isDefault)
	{
		com.e2u.test.obj.ObjectInf inf = null;
		try
		{
			Class clazz = null;
			if(isDefault)
			{
				clazz = Class.forName(name);
			}
			else
			{
				FileSystemClassLoader loader = new FileSystemClassLoader(SystemUtil.getRootDir());
				SystemUtil.debug("Try to load class " + name + " with " + loader);
				clazz = loader.loadClass(name);
			}
			
			showHierarchyClassLoader(clazz);
			
			inf = (com.e2u.test.obj.ObjectInf)clazz.newInstance();
			inf.sayHello();
		}
		catch(Exception e)
		{
			e.printStackTrace(System.out);
		}
		return inf;
	}
	
	private static void showHierarchyClassLoader(Class clazz)
	{
		while(!clazz.getName().equals("java.lang.Object"))
		{
			Class<?>[] infs = clazz.getInterfaces();
			for(int i = 0; i < infs.length; i++)
			{
				SystemUtil.showClassLoader("[INFS]: ", infs[i]);
			}
			
			clazz = clazz.getSuperclass();
			if("java.lang.Object".equals(clazz.getName()))
			{
				break;
			}
			SystemUtil.showClassLoader("[SUPER]: ", clazz);
		}
	}
	
	public static void classHotswap()
	{
		HotswapFileWatchdog hotswap = new HotswapFileWatchdog(SystemUtil.getRootDir(), "com/e2u/test/obj/Foo.class");
		hotswap.setDelay(1000 * 2);
		hotswap.start();
		
		try
		{
			Class clazz = Class.forName("com.e2u.test.obj.Foo");
			SystemUtil.invoke(clazz, "sayHello");
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		
		while(true)
		{
			try
			{
				Thread.sleep(1000 * 30);
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
		}
	}
	
	private static void classInSingleton()
	{
		String name = "com.e2u.test.obj.Singleton";
		Class clazz = null;
		
		SystemUtil.testAndInvokeClass(new FileSystemClassLoader(SystemUtil.getRootDir()), name, "sayHello");
		SystemUtil.testAndInvokeClass(new FileSystemClassLoader(SystemUtil.getRootDir()), name, "sayHello");
	}
	public static void main(String[] args)
	{
		classInDiffClassLoader();
		classInSingleton();
		classHotswap();
	}
}
